#include "glutproject.h"
#include <GL/glut.h>
#include <GL/gl.h>
#include <string>

using namespace bend2d;
using namespace std;

GlutProject* GlutProject::_Pointer = NULL;

GlutProject::GlutProject() 
{
    if(_Pointer != NULL)
        throw string("Cannot create two instances of GlutProject");
    _Pointer = this;
}

void GlutProject::DrawText(double x, double y, const string& text)
{
    glRasterPos3f(x,y,0);
    for(size_t i = 0; i < text.size(); ++i)
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, text[i]);
}

void GlutProject::Init(int argc, char* argv[])
{
    glutInit(&argc, argv);
    int width, height;
    string windowname;

    GetWindowSize(width, height);
    GetWindowName(windowname);
    glutInitWindowSize(width, height);

    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutCreateWindow(windowname.c_str());

    CustomInit();
    SetOrtho();

    glutIdleFunc(_IdleFunction);
    glutDisplayFunc(_RenderFunction);
    glutMouseFunc(_MouseFunction);
    glutKeyboardFunc(_KeyboardFunction);
}

void GlutProject::GetWindowSize(int& width, int& height)
{
    width = 640;
    height = 480;
}

void GlutProject::GetWindowName(string& windowname)
{
    windowname = "BEND2D - GlutProject - Simple";
}

void GlutProject::CustomInit()
{
    glEnable(GL_POINT_SMOOTH);
	glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void GlutProject::RenderFunction()
{
    ClearFunction();
    CustomRenderFunction();
    SwapBuffers();
}

void GlutProject::SwapBuffers()
{
    glutSwapBuffers();
}

void GlutProject::ClearFunction()
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
}

void GlutProject::CustomRenderFunction()
{
}

void GlutProject::CustomIdleFunction()
{
}

void GlutProject::CustomMouseFunction(int button, int state, int x, int y)
{
}

void GlutProject::CustomKeyboardFunction(unsigned char key, int x, int y)
{
}

void GlutProject::MainLoop()
{
    glutMainLoop();
}

void GlutProject::SetOrtho()
{
    int width, height;
    GetWindowSize(width, height);
    gluOrtho2D(0, width, 0, height);
}

void GlutProject::_RenderFunction()
{
    _Pointer->RenderFunction();
}

void GlutProject::_IdleFunction()
{
    _Pointer->CustomIdleFunction();
}

void GlutProject::_MouseFunction(int button, int state, int x, int y)
{
    _Pointer->CustomMouseFunction(button, state, x, y);
}

void GlutProject::_KeyboardFunction(unsigned char key, int x, int y)
{
    _Pointer->CustomKeyboardFunction(key, x, y);
}
